package com.wsoft.hr.pm.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wsoft.bpm.enums.ApproveStatus;
import com.wsoft.bpm.query.mapping.ExtraBusinessDataQuery;
import com.wsoft.bpm.service.ActivityCallAble;
import com.wsoft.bpm.service.WorkFlowService;
import com.wsoft.core.exception.Asserts;
import com.wsoft.core.service.CodeRuleService;
import com.wsoft.core.service.CommonMemberService;
import com.wsoft.core.utils.ExcelUtil;
import com.wsoft.core.utils.LoginUserUtil;
import com.wsoft.core.utils.SqlAuthDisableHolder;
import com.wsoft.core.vo.MemberVO;
import com.wsoft.entity.BaseEntity;
import com.wsoft.hr.pm.constant.HrPmCodeConstant;
import com.wsoft.hr.pm.constant.HrPmTargetGroupConstant;
import com.wsoft.hr.pm.entity.HrPmTargetEntity;
import com.wsoft.hr.pm.entity.HrPmTargetGroupEntity;
import com.wsoft.hr.pm.entity.sys.HrOrganizationEntity;
import com.wsoft.hr.pm.enums.*;
import com.wsoft.hr.pm.manager.HrPmTargetGroupManager;
import com.wsoft.hr.pm.manager.HrPmTargetManager;
import com.wsoft.hr.pm.mapper.HrPmTargetMapper;
import com.wsoft.hr.pm.query.target.TargetExportQuery;
import com.wsoft.hr.pm.query.target.TargetInsertQuery;
import com.wsoft.hr.pm.query.target.TargetListQuery;
import com.wsoft.hr.pm.query.target.TargetUpdateQuery;
import com.wsoft.hr.pm.service.IHrPmTargetService;
import com.wsoft.hr.pm.service.sys.IHrOrganizationService;
import com.wsoft.hr.pm.vo.target.TargetTemplateExportVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 指标库 服务实现类
 * </p>
 *
 * @author Z001
 * @since 2025年02月18日 09:04:55
 */
@Service
public class HrPmTargetServiceImpl extends ServiceImpl<HrPmTargetMapper, HrPmTargetEntity> implements IHrPmTargetService, ActivityCallAble {

    @Resource
    private HrPmTargetManager targetManager;
    @Resource
    private HrPmTargetGroupManager targetGroupManager;
    @Resource
    private CodeRuleService codeRuleService;
    @Resource
    private IHrOrganizationService organizationService;
    @Resource
    private WorkFlowService workFlowService;
    @Resource
    private CommonMemberService memberService;

    /**
     * 新增指标
     *
     * @param query
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertTarget(TargetInsertQuery query, boolean isSubmit) {
        if (query.getIsFormula() == 1 && StrUtil.isBlank(query.getFormulaValue())) {
            Asserts.fail("[hr.pm.formula.empty.error]");
        }
        HrPmTargetEntity entity = Convert.convert(HrPmTargetEntity.class, query);
        Object code = codeRuleService.initCode(HrPmCodeConstant.HR_PM_CODE, null, 1);
        entity.setTargetCode(String.valueOf(code));
        entity.setTargetStatus(TargetStatusEnum.NOT_SUBMIT.getType());
        if(null == query.getGroupId()){
            entity.setGroupId(HrPmTargetGroupConstant.HR_PM_DELETE_GROUP_DEFAULT);
        }
        String randomString = null;
        if (isSubmit) {
            randomString = RandomUtil.randomString(8);
            entity.setBusinessCode(randomString);
            entity.setTargetStatus(TargetStatusEnum.PENDING_APPROVAL.getType());
            entity.setStatus(ApproveStatus.DRAFT.getValue());
        } else {
            entity.setStatus(ApproveStatus.DRAFT.getValue());
        }
        entity.setHrOrgId(query.getHrOrgId());
        boolean b = targetManager.save(entity);
        if (b && isSubmit) {
            WorkFlowBusinessDataEnum dataEnum = WorkFlowBusinessDataEnum.TARGET_DETAIL;
            ExtraBusinessDataQuery extraBusinessDataQuery = new ExtraBusinessDataQuery(dataEnum.getBusinessType(), dataEnum.getBusinessValue(), Convert.convert(HashMap.class,entity), null);
            HashMap<String,Object> hashMap = new HashMap<>(1);
            HrOrganizationEntity hrOrganizationEntity = organizationService.getOrgById(query.getHrOrgId());
            if(null == hrOrganizationEntity || null == hrOrganizationEntity.getMemberId()){
                Asserts.fail("[hr.pm.org.leader.error]");
            }
            hashMap.put("orgLeader",hrOrganizationEntity.getMemberId());

            workFlowService.startProcess(ProcessKeyEnum.TARGET.getProcessKey(), ProcessKeyEnum.TARGET.getTableName(), randomString, extraBusinessDataQuery,hashMap);
        }
        return b;
    }

    /**
     * 新增个人指标
     *
     * @param query
     * @return
     */
    @Override
    public HrPmTargetEntity personTargetInsert(TargetInsertQuery query) {
        HrPmTargetEntity entity = Convert.convert(HrPmTargetEntity.class, query);
        entity.setEnableFlag(1);
        entity.setStatus(2);
        entity.setTargetStatus(TargetStatusEnum.STORE.getType());
        entity.setTargetType(TargetTypeEnum.REFERENCE.getType());
        entity.setHrOrgId(LoginUserUtil.getUserInfo().getHrOrgId());
        entity.setMemberId(LoginUserUtil.getUserInfo().getLoginUserVO().getId());
        targetManager.save(entity);
        return entity;
    }

    /**
     * 编辑指标
     *
     * @param query
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateTarget(TargetUpdateQuery query, boolean isSubmit) {
        if (query.getIsFormula() == 1 && StrUtil.isBlank(query.getFormulaValue())) {
            Asserts.fail("[hr.pm.formula.empty.error]");
        }
        HrPmTargetEntity targetInfo = this.getTargetInfo(query.getId());
        if (1 == query.getEnableFlag() && !TargetStatusEnum.STORE.getType().equals(targetInfo.getTargetStatus())) {
            //判断状态
            Asserts.fail("[hr.pm.target.status.error]");
        }
        if (TargetStatusEnum.PENDING_APPROVAL.getType().equals(targetInfo.getTargetStatus())) {
            //判断状态
            Asserts.fail("[hr.pm.target.status.error]");
        }
        HrPmTargetEntity entity = Convert.convert(HrPmTargetEntity.class, query);
        if(null == query.getGroupId()){
            entity.setGroupId(HrPmTargetGroupConstant.HR_PM_DELETE_GROUP_DEFAULT);
        }
        String randomString = null;
        if (isSubmit) {
            randomString = RandomUtil.randomString(8);
            entity.setBusinessCode(randomString);
            entity.setTargetStatus(TargetStatusEnum.PENDING_APPROVAL.getType());
            entity.setStatus(ApproveStatus.DRAFT.getValue());
        } else {
            entity.setStatus(ApproveStatus.DRAFT.getValue());
        }
        boolean b = targetManager.updateById(entity);
        if (b && isSubmit) {
            WorkFlowBusinessDataEnum dataEnum = WorkFlowBusinessDataEnum.TARGET_DETAIL;
            ExtraBusinessDataQuery extraBusinessDataQuery = new ExtraBusinessDataQuery(dataEnum.getBusinessType(), dataEnum.getBusinessValue(), null, entity.getTargetName());
            HashMap<String,Object> hashMap = new HashMap<>(1);
            HrOrganizationEntity hrOrganizationEntity = organizationService.getOrgById(query.getHrOrgId());
            if(null == hrOrganizationEntity || null == hrOrganizationEntity.getMemberId()){
                Asserts.fail("[hr.pm.org.leader.error]");
            }
            hashMap.put("orgLeader",hrOrganizationEntity.getMemberId());
            workFlowService.startProcess(ProcessKeyEnum.TARGET.getProcessKey(), ProcessKeyEnum.TARGET.getTableName(), randomString, extraBusinessDataQuery, hashMap);
        }
        return b;
    }

    /**
     * 个人指标修改
     *
     * @param query
     * @return
     */
    @Override
    public boolean personTargetUpdate(TargetUpdateQuery query) {
        HrPmTargetEntity entity = getPersonTargetInfo(query.getId());
        if (null == entity || !Objects.equals(LoginUserUtil.getUserInfo().getLoginUserVO().getId(), entity.getMemberId())) {
            Asserts.fail("[hr.pm.person.target.operation.error]");
        }
        HrPmTargetEntity convert = Convert.convert(HrPmTargetEntity.class, query);
        return targetManager.updateById(convert);
    }

    /**
     * 获取详情
     *
     * @param id
     * @return
     */
    @Override
    public HrPmTargetEntity getTargetInfo(Long id) {
        return targetManager.getById(id);
    }

    @Override
    public HrPmTargetEntity getPersonTargetInfo(Long id) {
        SqlAuthDisableHolder.open();
        HrPmTargetEntity entity = targetManager.getById(id);
        SqlAuthDisableHolder.close();
        return entity;
    }

    /**
     * 删除指标
     *
     * @param id
     * @return
     */
    @Override
    public boolean delete(Long id) {
        HrPmTargetEntity entity = targetManager.getById(id);
        Long memberId = LoginUserUtil.getUserInfo().getLoginUserVO().getId();
        if (entity.getMemberId() != null && !Objects.equals(memberId, entity.getMemberId())) {
            //个人指标无法删除
            Asserts.fail("[hr.pm.person.target.operation.error]");
        }
        return targetManager.removeById(id);
    }

    /**
     * 指标分页
     *
     * @param query
     * @return
     */
    @Override
    public PageInfo<HrPmTargetEntity> listTarget(TargetListQuery query, boolean isUser) {
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<HrPmTargetEntity> list = targetManager.list(query, isUser);
        return PageInfo.of(list);
    }

    /**
     * 指标导出
     *
     * @param query
     */
    @Override
    public ByteArrayOutputStream exportTarget(TargetExportQuery query) {
        TargetListQuery param = Convert.convert(TargetListQuery.class, query);
        List<HrPmTargetEntity> list = targetManager.list(param, false);
        List<TargetTemplateExportVO> data = new ArrayList<>();
        if (CollUtil.isNotEmpty(list)) {
            convertExcelData(list, data);
        }
        return ExcelUtil.exportExcel(null, data, TargetTemplateExportVO.class, query.getIncludeColumnList(), null, null, null, null);
    }

    /**
     * 模板导出
     *
     * @return
     */
    @Override
    public ByteArrayOutputStream templateExport() {
        return ExcelUtil.exportExcel(null, null, TargetTemplateExportVO.class, null, null, null, null, null);
    }

    /**
     * excel导入
     *
     * @param inputStream
     */
    @Override
    public void importExcel(InputStream inputStream) {
        List<TargetTemplateExportVO> targetInfoList = ExcelUtil.importExcel(inputStream, TargetTemplateExportVO.class);
        List<HrPmTargetEntity> targetList = new ArrayList<>();
        if (CollUtil.isNotEmpty(targetInfoList)) {
            List<HrPmTargetGroupEntity> groupEntityList = targetGroupManager.listAll();
            Map<String, Long> groupMap = groupEntityList.stream()
                    .collect(Collectors.toMap(
                            HrPmTargetGroupEntity::getName,
                            BaseEntity::getId,
                            (existingValue, newValue) -> newValue
                    ));
            Map<String, Long> targetMap = new HashMap<>(16);
            List<String> pTargetCodeList = targetInfoList.stream().map(TargetTemplateExportVO::getPTargetCode).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(pTargetCodeList)) {
                List<HrPmTargetEntity> targetEntityList = targetManager.getByCodes(pTargetCodeList);
                targetMap = targetEntityList.stream().collect(Collectors.toMap(HrPmTargetEntity::getTargetCode, BaseEntity::getId));
            }

            //全量组织
            List<HrOrganizationEntity> hrOrgList = organizationService.listAllHrOrgWithCache();
            Map<String, Long> hrOrgCodeMap = hrOrgList.stream().collect(Collectors.toMap(HrOrganizationEntity::getCode, BaseEntity::getId));

            List<MemberVO> memberList = memberService.getMemberList();
            Map<String, Long> memberMap = memberList.stream().collect(Collectors.toMap(MemberVO::getCode, MemberVO::getId, (existingValue, newValue) -> newValue));

            for (TargetTemplateExportVO exportVO : targetInfoList) {
                HrPmTargetEntity target = Convert.convert(HrPmTargetEntity.class, exportVO);
                if (StrUtil.isNotBlank(exportVO.getResultScoreMemberValue())) {
                    target.setResultScoreMemberValue(memberMap.get(exportVO.getResultScoreMemberValue()) == null ? "" : memberMap.get(exportVO.getResultScoreMemberValue()).toString());
                }
                target.setId(null);
                target.setHrOrgId(hrOrgCodeMap.get(exportVO.getHrOrgCode()));
                //转换分组
                if (StrUtil.isNotBlank(exportVO.getGroupName())) {
                    target.setGroupId(groupMap.get(exportVO.getGroupName()));
                }
                //上级转换
                if (StrUtil.isNotBlank(exportVO.getPTargetCode())) {
                    target.setPTargetId(targetMap.get(exportVO.getPTargetCode()));
                }
                target.setIsKey("是".equals(exportVO.getIsKey()) ? 1 : 0);
                if ("是".equals(exportVO.getTargetType().trim())) {
                    target.setTargetType(TargetTypeEnum.REFERENCE.getType());
                } else {
                    if (TargetTypeEnum.OUT_REFERENCE_ADD.getDesc().equals(exportVO.getAddReductionScore())) {
                        target.setTargetType(TargetTypeEnum.OUT_REFERENCE_ADD.getType());
                    } else if (TargetTypeEnum.OUT_REFERENCE_REDUCTION.getDesc().equals(exportVO.getAddReductionScore())) {
                        target.setTargetType(TargetTypeEnum.OUT_REFERENCE_REDUCTION.getType());
                    }
                    if (StrUtil.isNotBlank(exportVO.getTargetTypeValue())) {
                        target.setTargetTypeValue(new BigDecimal(exportVO.getTargetTypeValue()));
                    }
                }

                if (ScoreTypeEnum.AUTO.getDesc().equals(exportVO.getIsFormula())) {
                    target.setIsFormula(1);
                } else {
                    target.setIsFormula(0);
                }
                Object code = codeRuleService.initCode(HrPmCodeConstant.HR_PM_CODE, null, 1);
                target.setTargetCode(String.valueOf(code));
                target.setEnableFlag(0);
                target.setTargetStatus(TargetStatusEnum.NOT_SUBMIT.getType());
                target.setStatus(ApproveStatus.DRAFT.getValue());
                targetList.add(target);
            }
            if (CollUtil.isNotEmpty(targetList)) {
                targetManager.saveBatch(targetList);
            }
        }
    }


    /**
     * 批量更新 个人指标
     *
     * @param list
     * @return
     */
    @Override
    public boolean batchUpdatePersonTarget(List<HrPmTargetEntity> list) {
        return targetManager.updateBatchById(list);
    }

    @Override
    public boolean updateStatus(TargetUpdateQuery query) {
        HrPmTargetEntity entity = targetManager.getById(query.getId());
        if (null == entity || !ApproveStatus.APPROVED.getValue().equals(entity.getStatus())) {
            Asserts.fail("[hr.pm.target.status.error]");
        }
        if (query.getEnableFlag().equals(entity.getEnableFlag())) {
            return true;
        }
        entity.setEnableFlag(query.getEnableFlag());
        return targetManager.updateById(entity);
    }

    // ################################## 私有方法  ##################################

    /**
     * 转换 导出excel数据
     *
     * @param list
     * @param data
     */
    private void convertExcelData(List<HrPmTargetEntity> list, List<TargetTemplateExportVO> data) {
        //查询分组
        List<HrPmTargetGroupEntity> groupEntityList = targetGroupManager.listAll();
        Map<Long, String> groupMap = groupEntityList.stream().collect(Collectors.toMap(BaseEntity::getId, HrPmTargetGroupEntity::getName));

        for (HrPmTargetEntity hrPmTargetEntity : list) {
            TargetTemplateExportVO exportVO = Convert.convert(TargetTemplateExportVO.class, hrPmTargetEntity);
            if (StrUtil.isNotBlank(exportVO.getResultScoreMemberValue())) {
                MemberVO memberVO = memberService.getMemberInfo(Long.valueOf(exportVO.getResultScoreMemberValue()));
                if (null != memberVO) {
                    exportVO.setResultScoreMemberValue(memberVO.getCode() + "-" + memberVO.getName());
                }
            }
            //全量组织
            List<HrOrganizationEntity> hrOrgList = organizationService.listAllHrOrgWithCache();
            Map<Long, String> hrOrgNameMap = hrOrgList.stream().collect(Collectors.toMap(BaseEntity::getId, HrOrganizationEntity::getName));
            Map<Long, String> hrOrgCodeMap = hrOrgList.stream().collect(Collectors.toMap(BaseEntity::getId, HrOrganizationEntity::getCode));
            String hrOrgName = hrOrgNameMap.get(hrPmTargetEntity.getHrOrgId());
            String hrOrgCode = hrOrgCodeMap.get(hrPmTargetEntity.getHrOrgId());
            exportVO.setHrOrgCode(hrOrgCode);
            exportVO.setHrOrgName(hrOrgName);

            exportVO.setGroupName(groupMap.get(hrPmTargetEntity.getGroupId()));
            if (null != hrPmTargetEntity.getPTargetId()) {
                HrPmTargetEntity targetVO = targetManager.getById(hrPmTargetEntity.getPTargetId());
                String code = null == targetVO ? "" : targetVO.getTargetCode();
                exportVO.setPTargetCode(code);
            }
            //赋值基准内指标/加分/扣分项
            if (TargetTypeEnum.REFERENCE.getType().equals(hrPmTargetEntity.getTargetType())) {
                exportVO.setTargetType("是");
            } else {
                exportVO.setTargetType("否");
                if (TargetTypeEnum.OUT_REFERENCE_ADD.getType().equals(hrPmTargetEntity.getTargetType())) {
                    exportVO.setAddReductionScore(TargetTypeEnum.OUT_REFERENCE_ADD.getDesc());
                } else {
                    exportVO.setAddReductionScore(TargetTypeEnum.OUT_REFERENCE_REDUCTION.getDesc());
                }
            }
            //是否关键指标
            exportVO.setIsKey(hrPmTargetEntity.getIsKey() == 1 ? "是" : "否");
            exportVO.setIsFormula(hrPmTargetEntity.getIsFormula() == 1 ? "系统计算" : "手动评分");
            data.add(exportVO);
        }
    }


    // ################################## 工作流相关  ##################################

    @Override
    public String getProcessDefKey() {
        return ProcessKeyEnum.TARGET.getProcessKey();
    }

    @Override
    public void complete(String processDefKey, String processInstanceId, String businessKey) {

        HrPmTargetEntity entity = targetManager.getByBusinessCode(businessKey);
        entity.setTargetStatus(TargetStatusEnum.STORE.getType());
        targetManager.updateById(entity);
    }

    @Override
    public void back(String processDefKey, String processInstanceId, String businessKey) {
        HrPmTargetEntity entity = targetManager.getByBusinessCode(businessKey);
        entity.setTargetStatus(TargetStatusEnum.NOT_SUBMIT.getType());
        targetManager.updateById(entity);
    }
}
